package com.yami.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.dto.AgreeJoinDTO;
import com.yami.shop.bean.dto.GroupNiceDTO;
import com.yami.shop.bean.dto.UltraGroupSwitchDTO;
import com.yami.shop.bean.event.MeltSendGroupSysMsgEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.vo.MeltCloudGroupUserAdminVO;
import com.yami.shop.common.bean.PageDTO;
import com.yami.shop.common.bean.PageVO;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageUtil;
import com.yami.shop.common.util.StringUtils;
import com.yami.shop.dto.user.GroupAnnouncementDTO;
import com.yami.shop.dto.user.GroupNotificationMessageDTO;
import com.yami.shop.security.common.bo.UserInfoInTokenBO;
import com.yami.shop.security.common.util.AuthUserContext;
import com.yami.shop.service.*;
import com.yami.shop.user.common.service.UserGasInfoService;
import com.yami.shop.util.SendUtil;
import com.yami.shop.vo.advice.AdviceTxtVo;
import com.yami.shop.vo.group.*;
import com.yami.shop.vo.message.message.GroupMessageVo;
import com.yami.shop.vo.message.message.UltraGroupMessageVo;
import io.rong.RongCloud;
import io.rong.methods.group.Group;
import io.rong.methods.ultragroup.UltraGroup;
import io.rong.models.Result;
import io.rong.models.group.GroupMember;
import io.rong.models.group.GroupModel;
import io.rong.models.group.UserGroup;
import io.rong.models.response.GroupUserQueryResult;
import io.rong.models.ultragroup.UltraGroupModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.yami.shop.common.response.ServerResponseEntity.fail;
import static com.yami.shop.common.response.ServerResponseEntity.success;

/**
 * 群组服务
 */
@Service
@Slf4j
public class RongYunGroupServiceImpl {

    @Autowired
    private RongCloud rongCloud;

    private Group group;

    private UltraGroup ultraGroup;

    @PostConstruct
    public void init() {
        this.group = rongCloud.group;
        this.ultraGroup = rongCloud.ultraGroup;
    }

    @Autowired
    private MeltCloudGroupService groupService;

    @Autowired
    private MeltCloudGroupUserService groupUserService;

    @Autowired
    private MeltCloudChannelService channelService;

    @Autowired
    private ApiUtilServiceImpl apiUtilService;

    @Autowired
    private MeltCloudUserService userService;

    @Autowired
    private RongYunMsgServiceImpl rongYunMsgService;

    @Autowired
    private MeltCloudGroupUserInviteService meltCloudGroupUserInviteService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private UserGasInfoService userGasInfoService;

    @Autowired
    private MeltCloudUltraGroupCostService ultraGroupCostService;

    @Autowired
    private MeltCloudUltraGroupApplyService ultraGroupApplyService;

    @Autowired
    private MeltCloudUltraGroupRecordService ultraGroupRecordService;

    @Autowired
    private MeltCloudUserRemarkService userRemarkService;

    @Autowired
    private ShopDetailService shopDetailService;

    @Autowired
    private SysConfigService sysConfigService;

    /**
     * 创建群组
     * 内容: 先给系统存放一份群组信息，然后请求融云接 系统id对应的就是融云群组id。 创建完成后给这个群发送一条群组通知消息
     *
     * @param groupVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<MeltCloudGroup> create(GroupVo groupVo) throws Exception {
        UserInfoInTokenBO userTokenBO = AuthUserContext.get();
        if (Objects.nonNull(userTokenBO)) {
            if (userTokenBO.getSysType().equals(1)) {
                groupVo.setCreatorUserId("shop_" + userTokenBO.getUserId());
                groupVo.setShopId(userTokenBO.getShopId());
                groupVo.setPic(shopDetailService.getShopDetailByShopId(userTokenBO.getShopId()).getShopLogo());
            } else if (userTokenBO.getSysType().equals(2)) {
                groupVo.setCreatorUserId("plat_" + userTokenBO.getUserId());
                if (groupVo.getShopId() == null) {
                    groupVo.setShopId(0L);
                }
                groupVo.setPic("pingtai.png");
            }
            UserIdVo userIdVo = UserIdVo.builder().id(groupVo.getCreatorUserId()).build();
            groupVo.setUsers(Collections.singletonList(userIdVo));
        } else {
            if (Objects.nonNull(groupVo.getIsOfficial()) && groupVo.getIsOfficial() == 1) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "官方群只能在运维端创建！");
            }
            if (groupVo.getType() != null && groupVo.getType() == 1) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "只可创建普通群聊！");
            }
            //非官方群，群名称限制
            List<String> allShopShortNameList = shopDetailService.getAllShopShortNameList();
            String value = sysConfigService.getValue("GROUP_NAME_CHECK");//群敏感词设置
            if(StrUtil.isNotEmpty(value)){
                String[] split = value.split(",");
                allShopShortNameList.addAll(Arrays.asList(split));
            }
            if (CollectionUtil.isNotEmpty(allShopShortNameList)){
                for (String sensitiveUrl : allShopShortNameList) {
                    if (groupVo.getGroupName().contains(sensitiveUrl)){
                        throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "群名不得包含官方及平台名称等！");
                    }
                }
            }
        }
        if (StringUtils.isEmpty(groupVo.getCreatorUserId())) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "创建者不能为空！");
        }
        MeltCloudGroup cloudGroup = null;
        if (groupVo.getType() != null && groupVo.getType() == 1 && Objects.isNull(groupVo.getShopId())) {
            if (Objects.isNull(groupVo.getCostId())) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "请选择超级群资费套餐！");
            }
            MeltCloudUltraGroupApply apply = MeltCloudUltraGroupApply.builder()
                    .type(0).costId(groupVo.getCostId()).objId(groupVo.getCreatorUserId()).name(groupVo.getGroupName()).pic(groupVo.getPic()).isOfficial(groupVo.getIsOfficial())
                    .build();
            UltraGroupSwitchDTO ultraGroupSwitch = sysConfigService.getSysConfigObject(Constant.ULTRA_GROUP_SWITCH, UltraGroupSwitchDTO.class);
            if (!ultraGroupSwitch.getUserAudit()) {
                // 免审核-扣减gas-创建
                apply.setStatus(3);
                ultraGroupApplyService.save(apply);
                reduceGasAndCreateGroup(apply, true);
            } else {
                ultraGroupApplyService.save(apply);
            }
        } else {
            cloudGroup = createGroup(groupVo);
        }
        return success(cloudGroup);
    }

    /**
     * 扣减gas值——>超级群创建或续费
     * @param apply
     * @param isCreate true:创建群  false:群续费
     */
    public void reduceGasAndCreateGroup(MeltCloudUltraGroupApply apply, boolean isCreate) {
        if (!isCreate) {
            operationPermissionVerification(String.valueOf(apply.getGroupId()), "", false);
        }
        MeltCloudUltraGroupRecord record = MeltCloudUltraGroupRecord.builder()
                .groupApplyId(apply.getId()).name(apply.getName()).pic(apply.getPic()).isOfficial(apply.getIsOfficial())
                .build();
        MeltCloudUltraGroupCost cost = ultraGroupCostService.getById(apply.getCostId());
        if (Objects.isNull(cost)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "超级群资费套餐不存在，请重新选择！");
        }
        Integer energyValue = cost.getEnergyValue();
        String result = "true";
        if (apply.getType() == 1) {
            // 商家
            Long shopId = apply.getShopId();
            result = shopDetailService.consumptionGasByShopId(shopId, energyValue);
        } else {
            // 用户
            String userId = apply.getObjId();
            try{
                userGasInfoService.reduceGasNumberByUserId(userId, energyValue);
            }catch (Exception e) {
                result = e.getMessage();
            }
        }
        if (!result.equals("true")) {
            // 1.消耗能量值失败
            if (isCreate) {
                apply.setStatus(2);
                ultraGroupApplyService.updateById(apply);
            }
            String msg = result.length() > 500 ? result.substring(0, 500) : result;
            int s = isCreate ? 2 : 3;
            record.setStatus(s);
            record.setReason(msg);
            ultraGroupRecordService.save(record);
        } else {
            // 2.消耗能量值成功
            if (isCreate) {
                // 2.1 创建超级群
                UserIdVo userIdVo = UserIdVo.builder().id(apply.getObjId()).build();
                // 到期时间
                DateTime dateTime = DateUtil.offsetMonth(DateUtil.date(), cost.getMonths());
                DateTime expirationTime = DateUtil.endOfDay(dateTime);
                GroupVo groupVo = GroupVo.builder()
                        .creatorUserId(apply.getObjId()).shopId(apply.getShopId()).type(1).isOfficial(apply.getIsOfficial()).groupName(apply.getName())
                        .users(Collections.singletonList(userIdVo)).pic(apply.getPic()).expirationTime(expirationTime)
                        .build();
                try {
                    MeltCloudGroup group = createGroup(groupVo);
                    apply.setGroupId(group.getId());
                    apply.setStatus(3);
                    ultraGroupApplyService.updateById(apply);
                } catch (Exception e) {
                    apply.setStatus(2);
                    ultraGroupApplyService.updateById(apply);
                    record.setStatus(2);
                    String msg = e.getMessage().length() > 500 ? e.getMessage().substring(0, 500) : e.getMessage();
                    record.setReason(msg);
                    ultraGroupRecordService.save(record);
                }
            } else {
                // 2.2 超级群续费
                MeltCloudGroup group = groupService.getById(apply.getGroupId());
                DateTime date = DateUtil.date();
                int compare = DateUtil.compare(group.getExpirationTime(), date);
                if (compare <= 0) {
                    DateTime dateTime = DateUtil.offsetMonth(date, cost.getMonths());
                    DateTime expirationTime = DateUtil.endOfDay(dateTime);
                    group.setExpirationTime(expirationTime);
                } else {
                    DateTime dateTime = DateUtil.offsetMonth(group.getExpirationTime(), cost.getMonths());
                    group.setExpirationTime(dateTime);
                }
                group.setIsArrears(0);
                groupService.updateById(group);
                apply.setCancelRenewal(0);
                ultraGroupApplyService.updateById(apply);
                record.setStatus(4);
                ultraGroupRecordService.save(record);
            }
        }
    }


    @NotNull
    public MeltCloudGroup createGroup(GroupVo groupVo) throws Exception {
        String creatorUserId = groupVo.getCreatorUserId();
        Long shopId = groupVo.getShopId();
        String type = Objects.isNull(groupVo.getType()) ? "0" : groupVo.getType().toString();
        int isOfficial = groupVo.getIsOfficial() == null ? 0 : groupVo.getIsOfficial();
        String groupName = groupVo.getGroupName();
        MeltCloudUser user = userService.getById(creatorUserId);
        if (Objects.isNull(user)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "创建人不存在！");
        }
        if (type.equals("0") && shopId == null) {
            groupName = String.format("%s,%s", user.getUserName(), groupName);
        }
        String pic = StringUtils.isEmpty(groupVo.getPic()) && type.equals("1") ? "/2022/12/123.png" : groupVo.getPic();
        MeltCloudGroup groupSave = MeltCloudGroup.builder().groupName(groupName).creatorUserId(creatorUserId).type(type).unpushLevel(0).isOfficial(isOfficial).shopId(shopId).pics(pic).expirationTime(groupVo.getExpirationTime()).build();
        if(shopId != null ){
            groupSave.setIsRevise("1");
        }
        groupService.insertGroup(groupSave);
        // 2. 创建群组用户
        if (type.equals("0")) {
            List<UserIdVo> groups = groupVo.getUsers().stream().distinct().collect(Collectors.toList());
            if (shopId == null && groups.size() < 3) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "群组成员不能少于三个！");
            }
            List<MeltCloudGroupUser> groupUsers = Lists.newArrayList();
            List<MeltCloudUser> melUser = new ArrayList<>();
            for (UserIdVo userIdVo : groups) {
                MeltCloudGroupUser groupUser = MeltCloudGroupUser.builder().groupId(groupSave.getId()).userId(userIdVo.getId()).build();
                groupUsers.add(groupUser);
                MeltCloudUser byId = userService.getById(userIdVo.getId());
                MeltCloudUser meltCloudUser = new MeltCloudUser();
                meltCloudUser.setId(userIdVo.getId());
                meltCloudUser.setUserName(byId.getUserName());
                meltCloudUser.setUserToken(byId.getUserToken());
                meltCloudUser.setDelFlag(byId.getDelFlag());
                meltCloudUser.setUserPortrait(byId.getUserPortrait());
                melUser.add(meltCloudUser);
            }
            groupSave.setUsers(melUser);
            groupUserService.insertBatchGroupUsers(groupUsers);

            // 3. 调用融云api创建群组
            List<GroupMember> groupMembers = BeanUtil.copyToList(groups, GroupMember.class);
            GroupMember[] groupParam = groupMembers.toArray(new GroupMember[groupMembers.size()]);
            GroupModel param = new GroupModel(StrUtil.toString(groupSave.getId()), groupParam, groupName, null);
            Result result = group.create(param);

            //4. 给群组发送通知消息
            if (SendUtil.requestSuccess(result)) {
                String message = "";
                if (groups.size() > 1) {
                    List<String> users = groups.stream().map(UserIdVo::getId).collect(Collectors.toList());
                    List<MeltCloudUser> cloudUsers = userService.listByIds(users);
                    String finalCreatorUserId = creatorUserId;
                    List<String> names = cloudUsers.stream().filter(meltCloudUser -> !StrUtil.equals(StrUtil.toString(meltCloudUser.getId()), finalCreatorUserId))
                            .map(MeltCloudUser::getUserName).collect(Collectors.toList());
                    StringBuilder builder = new StringBuilder(user.getUserName() + "邀请了");
                    for (String name : names) {
                        builder.append(name);
                        builder.append("、");
                    }
                    message = String.format("%s进入了群聊", builder.substring(0, builder.toString().length() - 1));
                } else {
                    message = "创建群聊成功";
                }
                GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder()
                        .senderId("0").operatorUserId(StrUtil.toString(creatorUserId)).message(message).targetId(Arrays.asList(StrUtil.toString(groupSave.getId()))).operation("邀请通知消息").build();
                rongYunMsgService.sendGroupAdvice(dto);
                return groupSave;
            }
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "创建群组失败");
        } else if (type.equals("1")) {
            MeltCloudGroupUser groupUser = MeltCloudGroupUser.builder().groupId(groupSave.getId()).userId(creatorUserId).build();
            groupUserService.insertGroupUser(groupUser);

            UltraGroupModel param = new UltraGroupModel();
            param.setUserId(creatorUserId);
            param.setId(StrUtil.toString(groupSave.getId()));
            param.setName(groupName);
            Result result = ultraGroup.create(param);
            if (SendUtil.requestSuccess(result)) {
                MeltCloudChannel channel = MeltCloudChannel.builder().groupId(groupSave.getId()).channelId("RCDefault").channelName("默认频道").type(0).creatorUserId(creatorUserId).unpushLevel(0).build();
                channelService.save(channel);
                groupSave.setChannelId("RCDefault");
                GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder()
                        .senderId("0").operatorUserId(creatorUserId).message("创建群聊成功").targetId(Arrays.asList(StrUtil.toString(groupSave.getId()))).operation("通知消息").channelId(groupSave.getChannelId())
                        .build();
                rongYunMsgService.sendUltraGroupAdvice(dto);
                return groupSave;
            }
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "创建超级群组失败");
        } else {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "群类型异常！");
        }
    }


    /**
     * 退出群组
     * 退出群组后，如果是群组退出 那就修改其他人为新群主 删除历史消息
     *
     * @param groupVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> quit(GroupVo groupVo) throws Exception {
        ultraGroupExpireCheck(groupVo.getGroupId(), groupVo.getUserId(), false);
        //如果是群主自己退出，将其他人设置为群主
        MeltCloudGroup group = groupService.getById(groupVo.getGroupId());
        boolean isDismiss = false;
        @NotEmpty(message = "用户id不能为空") String quitUserId = groupVo.getUsers().get(0).getId();
        if (group.getCreatorUserId().equals(quitUserId)) {
            MeltCloudGroupUser one = groupUserService.getOne(Wrappers.lambdaQuery(MeltCloudGroupUser.class)
                    .eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId()).eq(MeltCloudGroupUser::getIsDel, 0).ne(MeltCloudGroupUser::getUserId, quitUserId)
                    .orderByAsc(MeltCloudGroupUser::getUserStatus).orderByAsc(MeltCloudGroupUser::getId).last("limit 1"));
            if (Objects.nonNull(one)) {
                group.setCreatorUserId(one.getUserId());
                groupService.updateById(group);
            } else {
                //无成员解散群聊
                isDismiss = true;
            }
        }
        //将这个人退出群聊
        LambdaQueryWrapper<MeltCloudGroupUser> eq = new LambdaQueryWrapper<MeltCloudGroupUser>()
                .eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId())
                .eq(MeltCloudGroupUser::getUserId, quitUserId)
                .eq(MeltCloudGroupUser::getIsDel, 0);
        List<MeltCloudGroupUser> groupUserList = groupUserService.list(eq);
        MeltCloudGroupUser meltCloudGroupUser = groupUserList.get(0);
        meltCloudGroupUser.setIsDel("1");
        meltCloudGroupUser.setIsManage("0");// 如果是管理员
        groupUserService.updateById(meltCloudGroupUser);
        //退群消息
        MeltCloudUser user = userService.getById(quitUserId);
        StringBuilder builder = new StringBuilder(user.getUserName() + "退出群聊");
        String message = builder.toString();
        GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder()
                .senderId("0")
                .operatorUserId(quitUserId)
                .message(message)
                .targetId(Arrays.asList(StrUtil.toString(groupVo.getGroupId())))
                .operation("通知消息")
                .build();
        //将这个人退出融云群聊,并发消息
        Result result;
        if (group.getType().equals("0")) {
            List<UserIdVo> groups = groupVo.getUsers();
            List<GroupMember> groupMembers = BeanUtil.copyToList(groups, GroupMember.class);
            GroupMember[] groupParam = groupMembers.toArray(new GroupMember[groupMembers.size()]);
            GroupModel param = new GroupModel(groupVo.getGroupId(), groupParam, null, null);
            result = this.group.quit(param);
            if (!isDismiss)
                rongYunMsgService.sendGroupAdvice(dto);
        } else {
            UltraGroupModel uParam = new UltraGroupModel();
            uParam.setId(groupVo.getGroupId());
            uParam.setUserId(quitUserId);
            result = ultraGroup.quit(uParam);
            if (!isDismiss) {
                dto.setChannelId("RCDefault");
                rongYunMsgService.sendUltraGroupAdvice(dto);
            }
        }
        if (SendUtil.requestSuccess(result)) {
            if (isDismiss) {
                dismissGroup(groupVo);
            }
            return success();
        } else {
            throw new YamiShopBindException("退出群组失败:" + result.getErrorMessage());
        }
    }

    /**
     * 被迫退出群组
     * 退出群组后，如果是群组退出 删除历史消息
     *
     * @param groupVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized ServerResponseEntity<String> quitPassive(GroupVo groupVo) throws Exception {
        operationPermissionVerification(groupVo.getGroupId(), groupVo.getUserId(), false);
        ultraGroupExpireCheck(groupVo.getGroupId(), groupVo.getUserId(), false);
        if (groupVo.getUsers().size() == 0) {
            throw new YamiShopBindException("请选择移除的用户");
        }
        // 1. 如果是群主自己退出，将其他人设置为群主
        MeltCloudGroup meltCloudGroup = groupService.getById(groupVo.getGroupId());
        if (ObjectUtil.isNull(meltCloudGroup)) {
            throw new YamiShopBindException("查询群失败");
        }

        LambdaQueryWrapper<MeltCloudGroupUser> notIn = new LambdaQueryWrapper<MeltCloudGroupUser>()
                .eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId())
                .notIn(MeltCloudGroupUser::getUserId, groupVo.getUsers().stream().map(UserIdVo::getId).collect(Collectors.toList()));
        Long count = groupUserService.count(notIn);
        if (count < 3) {
            throw new YamiShopBindException("剩余群成员不能少于三个");
        }
        LambdaQueryWrapper<MeltCloudGroupUser> in = new LambdaQueryWrapper<MeltCloudGroupUser>()
                .eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId())
                .ne(MeltCloudGroupUser::getUserId, meltCloudGroup.getCreatorUserId())
                .in(MeltCloudGroupUser::getUserId, groupVo.getUsers().stream().map(UserIdVo::getId).collect(Collectors.toList()));
        List<MeltCloudGroupUser> list = groupUserService.list(in);
        if (CollectionUtil.isEmpty(list)) {
            throw new YamiShopBindException("查询被踢群成员失败");
        }
        List<String> ids = list.stream().map(MeltCloudGroupUser::getUserId).collect(Collectors.toList());
        List<MeltCloudUser> userList = userService.list(ids);
        String groupNameNew = meltCloudGroup.getGroupName() + ",";
        for (MeltCloudUser user : userList) {
            groupNameNew = groupNameNew.replaceAll(user.getUserName() + ",", "");
        }
        meltCloudGroup.setGroupName(groupNameNew.substring(0, groupNameNew.length()-1));
        groupService.updateById(meltCloudGroup);
        //2. 将这些人退出群聊
        LambdaQueryWrapper<MeltCloudGroupUser> eq = new LambdaQueryWrapper<MeltCloudGroupUser>()
                .eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId())
                .in(MeltCloudGroupUser::getUserId, ids)
                .eq(MeltCloudGroupUser::getIsDel, 0);
        List<MeltCloudGroupUser> groupUserlist = groupUserService.list(eq);
        groupUserlist.forEach(s -> s.setIsDel("1"));
        groupUserService.updateBatchById(groupUserlist);

        //3. 将这个人退出融云群聊
        if (meltCloudGroup.getType().equals("0")) {
            List<GroupMember> groupMembers = new ArrayList<>();
            ids.forEach(s -> {
                GroupMember groupMember = new GroupMember();
                groupMember.setId(s);
                groupMembers.add(groupMember);
            });
            GroupMember[] groupParam = groupMembers.toArray(new GroupMember[groupMembers.size()]);
            GroupModel param = new GroupModel(groupVo.getGroupId(), groupParam, null, null);
            Result result = group.quit(param);
            if (SendUtil.requestSuccess(result)) {
                String names = userList.stream().map(MeltCloudUser::getUserName).collect(Collectors.joining("、"));
                GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder()
                        .senderId("0")
                        .operatorUserId(groupVo.getUserId())
                        .message(names + "被移出该群聊")
                        .targetId(Arrays.asList(groupVo.getGroupId()))
                        .operation("通知消息")
                        .build();
                rongYunMsgService.sendGroupAdvice(dto);
                return success();
            }
            throw new YamiShopBindException("退出群组失败:" + result.getErrorMessage());
        } else {
            Map<String, MeltCloudUser> userMap = userList.stream().collect(Collectors.toMap(MeltCloudUser::getId, Function.identity()));
            for (String userId : ids) {
                UltraGroupModel uParam = new UltraGroupModel();
                uParam.setId(groupVo.getGroupId());
                uParam.setUserId(userId);
                Result result = ultraGroup.quit(uParam);
                if (!SendUtil.requestSuccess(result)) {
                    throw new YamiShopBindException("退出超级群组失败:" + result.getErrorMessage());
                }
                StringBuilder builder = new StringBuilder(userMap.get(userId).getUserName() + "被移出该群聊");
                GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder()
                        .senderId("0")
                        .operatorUserId(groupVo.getUserId())
                        .message(builder.toString())
                        .targetId(Arrays.asList(groupVo.getGroupId()))
                        .operation("通知消息")
                        .channelId("RCDefault")
                        .build();
                rongYunMsgService.sendUltraGroupAdvice(dto);
            }
            return success();
        }

    }

    /**
     * 解散群组
     * 删除群组下所有用户。删除历史消息
     *
     * @param groupVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> dismiss(GroupVo groupVo) throws Exception {
        operationPermissionVerification(groupVo.getGroupId(), groupVo.getUserId(), false);
        ultraGroupExpireCheck(groupVo.getGroupId(), groupVo.getUserId(), false);
        return dismissGroup(groupVo);
    }

    @NotNull
    private ServerResponseEntity<String> dismissGroup(GroupVo groupVo) throws Exception {
        // 1. 删除这个群组
        MeltCloudGroup cloudGroup = groupService.getById(groupVo.getGroupId());
        cloudGroup.setIsDismiss("1");
        //修改群组状态为已删除
        groupService.updateById(cloudGroup);
        // 解散群组
        Result result;
        if (cloudGroup.getType().equals("0")) {
            List<UserIdVo> groups = groupVo.getUsers();
            List<GroupMember> groupMembers = BeanUtil.copyToList(groups, GroupMember.class);
            GroupMember[] groupParam = groupMembers.toArray(new GroupMember[groupMembers.size()]);
            GroupModel param = new GroupModel(groupVo.getGroupId(), groupParam, cloudGroup.getGroupName(), null);
            result = group.dismiss(param);
        } else {
            result = ultraGroup.dis(groupVo.getGroupId());
        }

        // 4. 撤回群主的
        if (SendUtil.requestSuccess(result)) {
            //删除群主历史记录
            UltraGroupMessageVo messageVo = UltraGroupMessageVo.builder()
                    .conversationType("3")
                    .fromUserId(String.valueOf(cloudGroup.getCreatorUserId()))
                    .targetId(groupVo.getGroupId())
                    .build();
            rongYunMsgService.historyClean(messageVo);
            UltraGroupMessageVo messageVoCre = UltraGroupMessageVo.builder()
                    .conversationType("6")
                    .fromUserId(String.valueOf(cloudGroup.getCreatorUserId()))
                    .targetId(groupVo.getGroupId())
                    .build();
            rongYunMsgService.historyClean(messageVoCre);
            //删除群主用户历史记录
            if (CollUtil.isNotEmpty(groupVo.getUsers())) {
                for (UserIdVo userIdVo : groupVo.getUsers()) {
                    UltraGroupMessageVo messageVos = UltraGroupMessageVo.builder()
                            .conversationType("3")
                            .fromUserId(String.valueOf(userIdVo.getId()))
                            .targetId(groupVo.getGroupId())
                            .build();
                    rongYunMsgService.historyClean(messageVos);
                }
            }
            return success();
        }
        throw new YamiShopBindException("解散群组失败:" + result.getErrorMessage());
    }

    /**
     * 刷新群组信息方法
     *
     * @param groupModelSyncVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> update(GroupModelSyncVo groupModelSyncVo) throws Exception {
        MeltCloudGroup one = groupService.getById(groupModelSyncVo.getId());
        if (Objects.isNull(one)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群聊不存在！");
        }
        if (one.getType().equals("0")) {
            if (StringUtils.isEmpty(groupModelSyncVo.getName())) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "群聊名称不能为空");
            }
            if (one.getIsRevise().equals("1")) {
                operationPermissionVerification(groupModelSyncVo.getId(), groupModelSyncVo.getUserId(), false);
            }
        } else {
            operationPermissionVerification(groupModelSyncVo.getId(), groupModelSyncVo.getUserId(), false);
            ultraGroupExpireCheck(groupModelSyncVo.getId(), groupModelSyncVo.getUserId(), false);
        }
        if(one.getIsOfficial()==0){
            //非官方群，群名称限制
            List<String> allShopShortNameList = shopDetailService.getAllShopShortNameList();
            String value = sysConfigService.getValue("GROUP_NAME_CHECK");//群敏感词设置
            if(StrUtil.isNotEmpty(value)){
                String[] split = value.split(",");
                allShopShortNameList.addAll(Arrays.asList(split));
            }
            if (CollectionUtil.isNotEmpty(allShopShortNameList)){
                for (String sensitiveUrl : allShopShortNameList) {
                    if (groupModelSyncVo.getName().contains(sensitiveUrl)){
                        throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "群名不得包含官方及平台名称等！");
                    }
                }
            }
        }
        MeltCloudGroup meltCloudGroup = MeltCloudGroup.builder()
                .id(Long.valueOf(groupModelSyncVo.getId()))
                .groupName(groupModelSyncVo.getName())
                .pics(groupModelSyncVo.getPic())
                .coverImg(groupModelSyncVo.getCoverImg())
                .build();
        groupService.updateById(meltCloudGroup);
        if (StringUtils.isNotEmpty(groupModelSyncVo.getName()) && !one.getGroupName().equals(groupModelSyncVo.getName())) {
            Result result;
            if (one.getType().equals("0")) {
                GroupModel param = BeanUtil.toBean(groupModelSyncVo, GroupModel.class);
                result = group.update(param);
            } else {
                UltraGroupModel param = BeanUtil.toBean(groupModelSyncVo, UltraGroupModel.class);
                result = ultraGroup.refresh(param);
            }
            if (SendUtil.requestSuccess(result))
                return success(groupModelSyncVo.getName());
            throw new YamiShopBindException("修改群名称失败:" + result.getErrorMessage());
        }
        return success();
    }

    /**
     * 发布群公告
     *
     * @param announcementDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> updateGroupAnnouncement(GroupAnnouncementDTO announcementDTO) throws Exception {
        operationPermissionVerification(String.valueOf(announcementDTO.getId()), announcementDTO.getCreatorUserId(), false);
        ultraGroupExpireCheck(String.valueOf(announcementDTO.getId()), announcementDTO.getCreatorUserId(), false);
        // 1. 发布群公告
        MeltCloudGroup meltCloudGroup = new MeltCloudGroup();
        meltCloudGroup.setId(announcementDTO.getId());
        meltCloudGroup.setGroupAnnouncement(announcementDTO.getGroupAnnouncement());
        groupService.updateById(meltCloudGroup);
        // 2. 发送群组通知消息
//        String content = "群公告\n" + announcementDTO.getGroupAnnouncement();
//        // 3. 发送群聊消息
//        AdviceTxtVo adviceTxtVo = AdviceTxtVo.builder()
//                .content(content)
//                .build();
//        GroupMessageVo build = GroupMessageVo.builder()
//                .content(adviceTxtVo)
//                .senderId(String.valueOf(announcementDTO.getCreatorUserId()))
//                .targetId(Arrays.asList(StrUtil.toString(meltCloudGroup.getId())))
//                .objectName("RC:TxtMsg")
//                .isIncludeSender(1)
//                .build();
//        rongYunMsgService.publishGroup(build);
        return success(meltCloudGroup.getGroupAnnouncement());
    }

    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> publishAnnouncement(GroupAnnouncementDTO announcementDTO) throws Exception {
        operationPermissionVerification(String.valueOf(announcementDTO.getId()), announcementDTO.getCreatorUserId(), false);
        ultraGroupExpireCheck(String.valueOf(announcementDTO.getId()), announcementDTO.getCreatorUserId(), false);
        // 1. 发布群公告
        MeltCloudGroup meltCloudGroup = BeanUtil.copyProperties(announcementDTO, MeltCloudGroup.class);
        groupService.updateById(meltCloudGroup);
        // 2. 发送群组通知消息
        String content = "群公告\n" + announcementDTO.getGroupAnnouncement();
        // 3. 发送群聊消息
        AdviceTxtVo adviceTxtVo = AdviceTxtVo.builder()
                .content(content)
                .build();
        GroupMessageVo build = GroupMessageVo.builder()
                .content(adviceTxtVo)
                .senderId(String.valueOf(announcementDTO.getCreatorUserId()))
                .targetId(Arrays.asList(StrUtil.toString(meltCloudGroup.getId())))
                .objectName("RC:TxtMsg")
                .isIncludeSender(1)
                .build();
        rongYunMsgService.publishGroup(build);
        return success(meltCloudGroup.getGroupAnnouncement());
    }

    /**
     * 修改用户群昵称
     *
     * @param groupNiceDTO
     * @return
     */
    public ServerResponseEntity<String> updateUserGroupNike(GroupNiceDTO groupNiceDTO) {
        ultraGroupExpireCheck(String.valueOf(groupNiceDTO.getGroupId()), groupNiceDTO.getUserId(), false);
        LambdaQueryWrapper<MeltCloudGroupUser> eq = new LambdaQueryWrapper<MeltCloudGroupUser>()
                .eq(MeltCloudGroupUser::getGroupId, groupNiceDTO.getGroupId())
                .eq(MeltCloudGroupUser::getUserId, groupNiceDTO.getUserId());
        //非官方群，群名称限制
        List<String> allShopShortNameList = shopDetailService.getAllShopShortNameList();
        String value = sysConfigService.getValue("GROUP_NAME_CHECK");//群敏感词设置
        if(StrUtil.isNotEmpty(value)){
            String[] split = value.split(",");
            allShopShortNameList.addAll(Arrays.asList(split));
        }
        if (CollectionUtil.isNotEmpty(allShopShortNameList)){
            for (String sensitiveUrl : allShopShortNameList) {
                if (groupNiceDTO.getUserGroupNikeName().contains(sensitiveUrl)){
                    throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "昵称不得包含官方及平台名称等！");
                }
            }
        }
        MeltCloudGroupUser user = groupUserService.getOne(eq);
        user.setGroupNikeName(groupNiceDTO.getUserGroupNikeName());
        groupUserService.updateById(user);
        return success(groupNiceDTO.getUserGroupNikeName());
    }

    /**
     * 查询群成员信息
     *
     * @param groupId
     * @return
     */
    public ServerResponseEntity<List<MeltCloudUser>> getInfo(String groupId) throws Exception {
        List<MeltCloudUser> groupsUser = userService.getGroupsUser(Long.valueOf(groupId), null,null,false);
        return success(groupsUser);
    }
    public ServerResponseEntity<Map<String,MeltCloudUser>> getUserInfoMap(String groupId, String userId) throws Exception {
        Map<String,MeltCloudUser> groupsUser = userService.getUserInfoMap(Long.valueOf(groupId), userId);
        return success(groupsUser);
    }

    /**
     * 查询群成员信息
     *
     * @param groupId
     * @return
     */
    public ServerResponseEntity<List<MeltCloudUser>> getInfo(String groupId, String userName,String userId) throws Exception {
        List<MeltCloudUser> groupsUser = userService.getGroupsUser(Long.valueOf(groupId), userName,userId,true);
        return success(groupsUser);
    }
    public ServerResponseEntity<Map<String,Object>> getUserInfoCount(String groupId,String userId) throws Exception {
        Map<String,Object> map = userService.getUserInfoCount(Long.valueOf(groupId),true,userId);
        return success(map);
    }


    /**
     * 获取群组成员
     *
     * @param groupId
     * @return
     * @throws Exception
     */
    public GroupUserQueryResult getUserInfo(String groupId) throws Exception {
        GroupModel param = new GroupModel()
                .setId(groupId);
        return group.get(param);
    }

    /**
     * 同步用户所属群组方法
     *
     * @param groupSyncVo
     * @return
     */
    public ServerResponseEntity<String> sync(GroupSyncVo groupSyncVo) {
        List<GroupModelSyncVo> groupModelSyncVos = groupSyncVo.getGroups();
        List<GroupModel> groupModels = BeanUtil.copyToList(groupModelSyncVos, GroupModel.class);
        GroupModel[] groupModelArray = groupModels.toArray(new GroupModel[groupModels.size()]);
        UserGroup param = new UserGroup(groupSyncVo.getId(), groupModelArray);
        try {
            Result result = group.sync(param);
            log.info("group.sync-result: {}", result);
            if (SendUtil.requestSuccess(result))
                return success();
            return fail(ResponseEnum.EXCEPTION);
        } catch (Exception exception) {
            log.info("group.sync-error: {}", exception.getMessage());
            return fail(ResponseEnum.EXCEPTION);
        }
    }

    /**
     * 用户加入指定群组
     *
     * @param groupVo
     * @return
     */
    public ServerResponseEntity<String> join(GroupVo groupVo) throws Exception {
        List<UserIdVo> groups = groupVo.getUsers().stream().distinct().collect(Collectors.toList());
        MeltCloudGroup byId = groupService.getById(groupVo.getGroupId());
        if (ObjectUtils.isEmpty(byId))
            return ServerResponseEntity.showFailMsg("未能查到该群聊，请刷新重试！");
        if (byId.getIsDismiss().equals("1"))
            return ServerResponseEntity.showFailMsg("该群组已解散，请刷新重试！");

        List<String> userIds = groups.stream().map(s -> s.getId()).collect(Collectors.toList());
        List<MeltCloudGroupUser> groupUsers = groupUserService.list(Wrappers.lambdaQuery(MeltCloudGroupUser.class).eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId()).in(MeltCloudGroupUser::getUserId, userIds).eq(MeltCloudGroupUser::getIsDel, 0));
        if (CollUtil.isNotEmpty(groupUsers)) {
            MeltCloudUser user = userService.getById(groupUsers.get(0).getUserId());
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, user.getUserName() + "已在该群中");
        }
        //type 1 前端页面请求 判断添加审核请求  2 后台直接调用添加群组方法加入群聊
        if (groupVo.getType() == 1 && !byId.getCreatorUserId().equals(groupVo.getUserId())) {
            MeltCloudGroupUser meltCloudGroupUser = groupUserService.getOne(new LambdaQueryWrapper<MeltCloudGroupUser>().eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId()).eq(MeltCloudGroupUser::getUserId, groupVo.getUserId()).eq(MeltCloudGroupUser::getIsManage, "1"));
            if (meltCloudGroupUser == null && byId.getIsInvite().equals("1")) {
                joinGroupAudit(groupVo, groups);
                return success();
            }
        }
        Result result = null;
        if (byId.getType().equals("0")) {
            List<GroupMember> groupMembers = BeanUtil.copyToList(groups, GroupMember.class);
            GroupMember[] groupParam = groupMembers.toArray(new GroupMember[groupMembers.size()]);
            GroupModel param = new GroupModel(groupVo.getGroupId(), groupParam, groupVo.getGroupName(), null);
            result = group.join(param);
        } else {
            for (UserIdVo userIdVo : groups) {
                UltraGroupModel param = new UltraGroupModel();
                param.setId(groupVo.getGroupId());
                param.setUserId(userIdVo.getId());
                result = ultraGroup.join(param);
                if (SendUtil.requestError(result)) {
                    groups.remove(userIdVo);
                    userIds.remove(userIdVo.getId());
                    log.error("=======进群失败======" + userIdVo.getId());
                }
            }
        }
        if (SendUtil.requestSuccess(result)) {
            log.info("===========进群成功==========");
            List<MeltCloudGroupUser> groupUserList = Lists.newArrayList();
            List<MeltCloudGroupUser> list = groupUserService.list(new LambdaQueryWrapper<MeltCloudGroupUser>().eq(MeltCloudGroupUser::getGroupId, groupVo.getGroupId()).in(MeltCloudGroupUser::getUserId, userIds));
            Map<String, MeltCloudGroupUser> groupUserMap = list.stream().collect(Collectors.toMap(MeltCloudGroupUser::getUserId, Function.identity()));
            for (UserIdVo userIdVo : groups) {
                MeltCloudGroupUser meltCloudGroupUser = groupUserMap.get(userIdVo.getId());
                if (ObjectUtil.isEmpty(meltCloudGroupUser)) {
                    MeltCloudGroupUser groupUser = MeltCloudGroupUser.builder()
                            .groupId(Long.valueOf(groupVo.getGroupId())).userId(userIdVo.getId()).build();
                    groupUserList.add(groupUser);
                } else {
                    if (meltCloudGroupUser.getIsDel().equals("1")) {
                        meltCloudGroupUser.setIsDel("0");
                        meltCloudGroupUser.setIsManage("0");
                        meltCloudGroupUser.setGroupNikeName(null);
                        groupUserList.add(meltCloudGroupUser);
                    } else {
                        userIds.remove(userIdVo.getId());
                        log.error("=======已在群中======" + userIdVo.getId());
                    }
                }
            }
            if (CollUtil.isNotEmpty(groupUserList)) {
                groupUserService.saveOrUpdateBatch(groupUserList);
            }
            //4. 给群组发送通知消息
            if (userIds.size() > 0) {
                MeltCloudUser user = userService.getById(StrUtil.isNotEmpty(groupVo.getUserId()) ? groupVo.getUserId() : byId.getCreatorUserId());
                List<MeltCloudUser> cloudUsers = userService.listByIds(userIds);
                String names = cloudUsers.stream().map(MeltCloudUser::getUserName).collect(Collectors.joining("、"));
                String message = String.format("%s进入了群聊", user.getUserName() + "邀请了" + names);
                GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder().senderId("0").operatorUserId(byId.getCreatorUserId()).message(message).targetId(Arrays.asList(groupVo.getGroupId())).operation("邀请通知消息").build();
                if (byId.getType().equals("0")) {
                    rongYunMsgService.sendGroupAdvice(dto);
                } else {
                    dto.setChannelId("RCDefault");
                    rongYunMsgService.sendUltraGroupAdvice(dto);
                }
            }
            return success();
        }
        throw new YamiShopBindException("加入群聊失败");
    }

    @Nullable
    private void joinGroupAudit(GroupVo groupVo, List<UserIdVo> groups) {
        for (UserIdVo userIdVo : groups) {
            MeltCloudUser meltCloudUser = userService.getById(userIdVo.getId());
            LambdaQueryWrapper<MeltCloudGroupUserInvite> getmelGroup = new LambdaQueryWrapper<MeltCloudGroupUserInvite>().eq(MeltCloudGroupUserInvite::getGroupId, groupVo.getGroupId()).eq(MeltCloudGroupUserInvite::getUserId, userIdVo.getId());
            MeltCloudGroupUserInvite one = meltCloudGroupUserInviteService.getOne(getmelGroup);
            if (ObjectUtils.isNotEmpty(one)) {
                if (one.getStatus() == 0) {
                    String userName = meltCloudUser.getUserName();
                    MeltCloudUserRemark userRemark = userRemarkService.getOne(Wrappers.lambdaQuery(MeltCloudUserRemark.class).eq(MeltCloudUserRemark::getType, 1).eq(MeltCloudUserRemark::getUserId, groupVo.getUserId()).eq(MeltCloudUserRemark::getObjId, userIdVo.getId()));
                    if (Objects.nonNull(userRemark) && StringUtils.isNotEmpty(userRemark.getRemark())) {
                        userName = userRemark.getRemark();
                    }
                    throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户" + userName + "在待审核列表！");
                }else{
                    // 已拒绝 修改 待审核
                    LambdaUpdateWrapper<MeltCloudGroupUserInvite> updateWrapper = new LambdaUpdateWrapper<MeltCloudGroupUserInvite>()
                            .eq(MeltCloudGroupUserInvite::getGroupId, groupVo.getGroupId()).eq(MeltCloudGroupUserInvite::getUserId, userIdVo.getId())
                            .set(MeltCloudGroupUserInvite::getStatus, 0).set(MeltCloudGroupUserInvite::getInviteUserId, groupVo.getUserId()).set(MeltCloudGroupUserInvite::getCreateTime, new Date());
                    meltCloudGroupUserInviteService.update(updateWrapper);
                    continue;
                }
            }
            //组装参数 添加审核表
            MeltCloudGroupUserInvite meltCloudGroupUserInvite = new MeltCloudGroupUserInvite();
            meltCloudGroupUserInvite.setGroupId(Long.valueOf(groupVo.getGroupId()));
            meltCloudGroupUserInvite.setStatus(0);
            meltCloudGroupUserInvite.setInviteUserId(groupVo.getUserId());
            meltCloudGroupUserInvite.setUserId(userIdVo.getId());
            meltCloudGroupUserInvite.setUserName(meltCloudUser.getUserName());
            meltCloudGroupUserInvite.setUserPortrait(meltCloudUser.getUserPortrait());
            meltCloudGroupUserInvite.setCreateTime(new Date());
            meltCloudGroupUserInviteService.save(meltCloudGroupUserInvite);
        }
    }

    //扫码加入群聊
    public ServerResponseEntity<String> ScanGroupJoin(GroupScanVo groupScanVo) throws Exception {
        MeltCloudGroup byId = groupService.getById(groupScanVo.getGroupId());
        //群聊状态
        if (byId.getIsInvite().equals("1")) {
            if (StringUtils.isNotEmpty(groupScanVo.getJoinType()) && groupScanVo.getJoinType().equals("01")) {
                return ServerResponseEntity.showFailMsg("群组开启审核，暂不支持用户加入");
            }
            return ServerResponseEntity.showFailMsg("群组开启审核，暂不支持扫码加入");
        }
        LambdaQueryWrapper<MeltCloudGroupUser> eq = new LambdaQueryWrapper<MeltCloudGroupUser>().eq(MeltCloudGroupUser::getGroupId, groupScanVo.getGroupId()).eq(MeltCloudGroupUser::getUserId, groupScanVo.getUserId());
        List<MeltCloudGroupUser> listAll = groupUserService.list(eq);
        List<MeltCloudGroupUser> list = listAll.stream().filter(s -> "0".equals(s.getIsDel())).collect(Collectors.toList());
        if (list.size() > 0) {
            // 该用户已加入群聊
            return success("201");
        }
        //融云-加入群聊
        Result result;
        if (byId.getType().equals("0")) {
            UserIdVo userIdVos = new UserIdVo();
            userIdVos.setId(groupScanVo.getUserId());
            List<UserIdVo> groups = new ArrayList<>();
            groups.add(userIdVos);
            List<GroupMember> groupMembers = BeanUtil.copyToList(groups, GroupMember.class);
            GroupMember[] groupParam = groupMembers.toArray(new GroupMember[groupMembers.size()]);
            GroupModel param = new GroupModel(groupScanVo.getGroupId(), groupParam, groupScanVo.getGroupName(), null);
            result = group.join(param);
        } else {
            UltraGroupModel uParam = new UltraGroupModel();
            uParam.setId(groupScanVo.getGroupId());
            uParam.setUserId(groupScanVo.getUserId());
            result = ultraGroup.join(uParam);
        }
        if (SendUtil.requestSuccess(result)) {
            List<MeltCloudGroupUser> groupUserList = listAll.stream().filter(s -> "1".equals(s.getIsDel())).collect(Collectors.toList());
            if (groupUserList.size() > 0) {
                MeltCloudGroupUser meltCloudGroupUsers = groupUserList.get(0);
                meltCloudGroupUsers.setIsDel("0");
                meltCloudGroupUsers.setIsManage("0");
                meltCloudGroupUsers.setGroupNikeName(null);
                groupUserService.updateById(meltCloudGroupUsers);
            } else {
                //加入群组
                MeltCloudGroupUser groupUser = MeltCloudGroupUser
                        .builder()
                        .groupId(Long.valueOf(groupScanVo.getGroupId()))
                        .userId(groupScanVo.getUserId())
                        .build();
                groupUserService.insertGroupUser(groupUser);
            }
            log.info("=========={}加入{}创建的群聊{}完成======去发进群消息===", groupScanVo.getUserId(), byId.getCreatorUserId(), groupScanVo.getGroupId());
            //4. 给群组发送通知消息
            if (!StrUtil.equals(groupScanVo.getUserId(), byId.getCreatorUserId())) {
                MeltCloudUser cloudUser = userService.getById(groupScanVo.getUserId());
                String message = String.format("%s扫码进入了群聊", cloudUser.getUserName());
                if (StringUtils.isNotEmpty(groupScanVo.getJoinType()) && groupScanVo.getJoinType().equals("01")) {
                    message = String.format("%s搜索进入了群聊", cloudUser.getUserName());
                }
                GroupNotificationMessageDTO dto = GroupNotificationMessageDTO.builder()
                        .senderId("0")
                        .operatorUserId(StrUtil.toString(byId.getCreatorUserId()))
                        .message(message)
                        .targetId(Arrays.asList(StrUtil.toString(groupScanVo.getGroupId())))
                        .operation("邀请通知消息")
                        .build();
                if (byId.getType().equals("0")) {
                    rongYunMsgService.sendGroupAdvice(dto);
                } else {
                    dto.setChannelId("RCDefault");
                    rongYunMsgService.sendUltraGroupAdvice(dto);
                }
                log.info("=====进群消息发送完成======");
            }
            return success();
        } else {
            throw new YamiShopBindException("加入群聊失败");
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> setUpAdmin(String[] userIds, String groupId, String currentUserId) {
        operationPermissionVerification(groupId, currentUserId, false);
        ultraGroupExpireCheck(groupId, currentUserId, false);
        for(String userId : userIds){
            UpdateWrapper<MeltCloudGroupUser> userUpdateWrapper = new UpdateWrapper<>();
            userUpdateWrapper.eq("group_id",groupId);
            userUpdateWrapper.eq("user_id",userId);
            MeltCloudGroupUser meltCloudGroupUser = new MeltCloudGroupUser();
            meltCloudGroupUser.setIsManage("1");
            boolean update = groupUserService.update(meltCloudGroupUser, userUpdateWrapper);
            if(!update){
                throw new YamiShopBindException("设置管理员失败");
            }
            List<String> toUserId = new ArrayList<>();
            toUserId.add(userId);
            MeltSendGroupSysMsgEvent build = MeltSendGroupSysMsgEvent.builder().targetId(groupId).message("群主设置你为管理员").toUserId(toUserId).build();
            applicationContext.publishEvent(build);
        }
        return success();
    }

    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> cancelAdmin(String[] userId, String groupId, String cUserId) {
        operationPermissionVerification(groupId, cUserId, false);
        ultraGroupExpireCheck(groupId, cUserId, false);
        for(String userIds:userId){
            UpdateWrapper<MeltCloudGroupUser> userUpdateWrapper = new UpdateWrapper<>();
            userUpdateWrapper.eq("group_id",groupId);
            userUpdateWrapper.eq("user_id",userIds);
            MeltCloudGroupUser meltCloudGroupUser = new MeltCloudGroupUser();
            meltCloudGroupUser.setIsManage("0");
            boolean update = groupUserService.update(meltCloudGroupUser, userUpdateWrapper);
            if(!update){
                throw new YamiShopBindException("取消管理员失败");
            }
            List<String> toUserId = new ArrayList<>();
            toUserId.add(userIds);
            MeltSendGroupSysMsgEvent build = MeltSendGroupSysMsgEvent.builder().targetId(groupId).message("群主取消了你的管理员").toUserId(toUserId).build();
            applicationContext.publishEvent(build);
        }
        return success();
    }

    /**
     * 操作权限验证
     * @param groupId 群
     * @param cUserId 当前用户
     * @param onlyLeader 仅校验群主
     */
    private void operationPermissionVerification(String groupId, String cUserId, boolean onlyLeader) {
        UserInfoInTokenBO userTokenBO = AuthUserContext.get();
        if (Objects.nonNull(userTokenBO)) {
            if (userTokenBO.getSysType().equals(1)) {
                cUserId = "shop_" + userTokenBO.getUserId();
            } else if (userTokenBO.getSysType().equals(2)) {
                cUserId = "plat_" + userTokenBO.getUserId();
            } else if (userTokenBO.getSysType().equals(0)) {
                cUserId = userTokenBO.getUserId();
            }
        }
        if (StringUtils.isEmpty(cUserId)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "操作人不能为空！");
        }
        MeltCloudGroup group = groupService.getById(groupId);
        if (group == null || group.getIsDismiss().equals("1")) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群不存在或已解散！");
        }
        if (!group.getCreatorUserId().equals(cUserId)) {
            if (onlyLeader) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "您非群主不能操作！");
            } else {
                MeltCloudGroupUser groupUser = groupUserService.getOne(Wrappers.lambdaQuery(MeltCloudGroupUser.class).eq(MeltCloudGroupUser::getGroupId, groupId).eq(MeltCloudGroupUser::getUserId, cUserId).eq(MeltCloudGroupUser::getIsManage, 1));
                if (Objects.isNull(groupUser)) {
                    throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "您非群主或管理员不能操作！");
                }
            }
        }
    }


    public ServerResponseEntity<List<MeltCloudGroupUserAdminVO>> getGroupAdminList(String groupId, String userId) {
        List<MeltCloudGroupUserAdminVO> meltCloudGroupUserAdminVOList = new ArrayList<>();
        LambdaQueryWrapper<MeltCloudGroupUser> eq = new LambdaQueryWrapper<MeltCloudGroupUser>().eq(MeltCloudGroupUser::getGroupId, groupId).eq(MeltCloudGroupUser::getIsManage, 1).eq(MeltCloudGroupUser::getIsDel,0);
        List<MeltCloudGroupUser> groupUserList = groupUserService.list(eq);
        if(groupUserList.size()>0){
            List<String> userIds = groupUserList.stream().map(MeltCloudGroupUser::getUserId).collect(Collectors.toList());
            List<MeltCloudUser> users = userService.listByIds(userIds);
            Map<String, String> remarkMap = new HashMap<>();
            if (StringUtils.isNotEmpty(userId)) {
                List<MeltCloudUserRemark> list = userRemarkService.list(Wrappers.lambdaQuery(MeltCloudUserRemark.class)
                        .eq(MeltCloudUserRemark::getUserId, userId).eq(MeltCloudUserRemark::getType, 1).in(MeltCloudUserRemark::getObjId, userIds));
                remarkMap = list.stream().collect(Collectors.toMap(MeltCloudUserRemark::getObjId, MeltCloudUserRemark::getRemark));
            }
            for(MeltCloudUser user : users){
                MeltCloudGroupUserAdminVO meltCloudGroupUserAdminVO = new MeltCloudGroupUserAdminVO();
                meltCloudGroupUserAdminVO.setUserId(user.getId());
                String name = StringUtils.isEmpty(remarkMap.get(user.getId())) ? user.getUserName() : remarkMap.get(user.getId());
                meltCloudGroupUserAdminVO.setUserName(name);
                meltCloudGroupUserAdminVO.setUserPortrait(user.getUserPortrait());
                meltCloudGroupUserAdminVOList.add(meltCloudGroupUserAdminVO);
            }
        }
        return ServerResponseEntity.success(meltCloudGroupUserAdminVOList);
    }

    public ServerResponseEntity<PageVO<MeltCloudGroupUserInvite>> getGroupInviteList(PageDTO pageDTO, String groupId, String userId) {
        LambdaQueryWrapper<MeltCloudGroupUserInvite> eq = new LambdaQueryWrapper<MeltCloudGroupUserInvite>().eq(MeltCloudGroupUserInvite::getGroupId, groupId).eq(MeltCloudGroupUserInvite::getStatus,0).orderByDesc(MeltCloudGroupUserInvite::getCreateTime);
        List<MeltCloudGroupUserInvite> list1 = meltCloudGroupUserInviteService.list(eq);
        PageVO<MeltCloudGroupUserInvite> page = new PageVO<>();
        if(list1.size()>0){
            Set<String> inviteUserIdSet = list1.stream().map(MeltCloudGroupUserInvite::getInviteUserId).collect(Collectors.toSet());
            Set<String> userIds = list1.stream().map(MeltCloudGroupUserInvite::getUserId).collect(Collectors.toSet());
            userIds.addAll(inviteUserIdSet);
            List<MeltCloudUser> users = userService.listByIds(userIds);
            Map<String, String> userMap = users.stream().collect(Collectors.toMap(MeltCloudUser::getId, MeltCloudUser::getUserName));
            users = users.stream().filter(s->"1".equals(s.getDelFlag())).collect(Collectors.toList());
            List<String> idRemoves = users.stream().map(s -> s.getId()).collect(Collectors.toList());
            Map<String, String> remarkMap = new HashMap<>();
            if (StringUtils.isNotEmpty(userId)) {
                List<MeltCloudUserRemark> list = userRemarkService.list(Wrappers.lambdaQuery(MeltCloudUserRemark.class).eq(MeltCloudUserRemark::getUserId, userId).eq(MeltCloudUserRemark::getType, 1).in(MeltCloudUserRemark::getObjId, userIds));
                remarkMap = list.stream().collect(Collectors.toMap(MeltCloudUserRemark::getObjId, MeltCloudUserRemark::getRemark));
            }
            //获取返回数据
            LambdaQueryWrapper<MeltCloudGroupUserInvite> eq1 = new LambdaQueryWrapper<MeltCloudGroupUserInvite>()
                    .eq(MeltCloudGroupUserInvite::getGroupId, groupId)
                    .eq(MeltCloudGroupUserInvite::getStatus,0)
                    .notIn(idRemoves.size()>0, MeltCloudGroupUserInvite::getUserId,idRemoves)
                    .notIn(idRemoves.size()>0,MeltCloudGroupUserInvite::getInviteUserId,idRemoves)
                    .orderByDesc(MeltCloudGroupUserInvite::getCreateTime);
           page = PageUtil.doPage(pageDTO, () ->meltCloudGroupUserInviteService.list(eq1));
            if(page.getList().size()>0){
                for(MeltCloudGroupUserInvite meltCloudGroupUserInvite : page.getList()){
                    if (StringUtils.isNotEmpty(userId) && StringUtils.isNotEmpty(remarkMap.get(meltCloudGroupUserInvite.getUserId()))) {
                        meltCloudGroupUserInvite.setUserName(remarkMap.get(meltCloudGroupUserInvite.getUserId()));
                    } else {
                        meltCloudGroupUserInvite.setUserName(userMap.get(meltCloudGroupUserInvite.getUserId()));
                    }
                    if (StringUtils.isNotEmpty(userId) && StringUtils.isNotEmpty(remarkMap.get(meltCloudGroupUserInvite.getInviteUserId()))) {
                        meltCloudGroupUserInvite.setInviteUserIdName(remarkMap.get(meltCloudGroupUserInvite.getInviteUserId()));
                    } else {
                        meltCloudGroupUserInvite.setInviteUserIdName(userMap.get(meltCloudGroupUserInvite.getInviteUserId()));
                    }
                }
            }
        }
        return ServerResponseEntity.success(page);
    }

    public synchronized ServerResponseEntity<String> isAgreeJoin(AgreeJoinDTO joinDTO) throws Exception {
        operationPermissionVerification(joinDTO.getGroupId(), joinDTO.getCurrentUserId(), false);
        ultraGroupExpireCheck(joinDTO.getGroupId(), joinDTO.getCurrentUserId(), false);
        MeltCloudGroup group = groupService.getById(joinDTO.getGroupId());
        LambdaQueryWrapper<MeltCloudGroupUserInvite> eq = new LambdaQueryWrapper<MeltCloudGroupUserInvite>()
                .eq(MeltCloudGroupUserInvite::getGroupId, joinDTO.getGroupId()).eq(MeltCloudGroupUserInvite::getUserId, joinDTO.getUserId()).eq(MeltCloudGroupUserInvite::getStatus,0);
        MeltCloudGroupUserInvite one = meltCloudGroupUserInviteService.getOne(eq);
        if(ObjectUtils.isEmpty(one)){
            return ServerResponseEntity.showFailMsg("未查到该用户,请刷新重试");
        }
        if(1==joinDTO.getStatus()){
            //组装加入群聊方式
            List<UserIdVo> users = new ArrayList<>();
            UserIdVo userIdVo = new UserIdVo();
            userIdVo.setId(joinDTO.getUserId());
            users.add(userIdVo);
            // 邀请用户加入指定群聊
            GroupVo groupVo = new GroupVo();
            groupVo.setGroupId(joinDTO.getGroupId());
            groupVo.setUsers(users);
            groupVo.setGroupName(group.getGroupName());
            groupVo.setCreatorUserId(group.getCreatorUserId());
            groupVo.setUserId(one.getInviteUserId()); // 邀请人
            groupVo.setType(2);
            this.join(groupVo);
        }
        //修改审核通过/拒绝状态
        one.setStatus(joinDTO.getStatus());
        meltCloudGroupUserInviteService.updateById(one);
        return ServerResponseEntity.success();
    }

    public ServerResponseEntity<String> isInviteBygroupId(String groupId,String isInvite, String userId) {
        operationPermissionVerification(groupId, userId, false);
        ultraGroupExpireCheck(groupId, userId, false);
        LambdaUpdateWrapper<MeltCloudGroup> set = new LambdaUpdateWrapper<MeltCloudGroup>().eq(MeltCloudGroup::getId, groupId).set(MeltCloudGroup::getIsInvite, isInvite);
        boolean update = groupService.update(set);
        if(update){
            return ServerResponseEntity.success();
        }else{
            return ServerResponseEntity.showFailMsg("系统繁忙，请稍后重试");
        }
    }

    public ServerResponseEntity<String> isReviseBygroupId(String groupId, String isRevise, String userId) {
        operationPermissionVerification(groupId, userId, false);
        ultraGroupExpireCheck(groupId, userId, false);
        LambdaUpdateWrapper<MeltCloudGroup> set = new LambdaUpdateWrapper<MeltCloudGroup>().eq(MeltCloudGroup::getId, groupId).set(MeltCloudGroup::getIsRevise, isRevise);
        boolean update = groupService.update(set);
        if(update){
            return ServerResponseEntity.success();
        }else{
            return ServerResponseEntity.showFailMsg("系统繁忙，请稍后重试");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> changeLeader(GroupLeadVo groupLeadVo) {
        operationPermissionVerification(groupLeadVo.getGroupId(), groupLeadVo.getCurrentUserId(), true);
        ultraGroupExpireCheck(groupLeadVo.getGroupId(), groupLeadVo.getCurrentUserId(), false);
        MeltCloudGroup group = groupService.getById(groupLeadVo.getGroupId());
        if (group.getCreatorUserId().equals(groupLeadVo.getToUserId()))
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该用户已是群主！");
        group.setCreatorUserId(groupLeadVo.getToUserId());
        boolean update = groupService.updateById(group);
        if(update){
            LambdaQueryWrapper<MeltCloudGroupUser> eq = new LambdaQueryWrapper<MeltCloudGroupUser>().eq(MeltCloudGroupUser::getUserId, groupLeadVo.getToUserId()).eq(MeltCloudGroupUser::getGroupId, groupLeadVo.getGroupId());
            MeltCloudGroupUser one = groupUserService.getOne(eq);
            if(one.getIsManage().equals("1")){
                one.setIsManage("0");
                groupUserService.updateById(one);
            }
            List<String> toUserId = new ArrayList<>();
            toUserId.add(groupLeadVo.getToUserId());
            MeltSendGroupSysMsgEvent build = MeltSendGroupSysMsgEvent.builder().targetId(groupLeadVo.getGroupId()).message("你已成为新群主").toUserId(toUserId).build();
            applicationContext.publishEvent(build);
            return ServerResponseEntity.success();
        }else{
            return ServerResponseEntity.showFailMsg("系统繁忙，请稍后重试");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity publicByGroupId(Long groupId, String currentUserId) {
        operationPermissionVerification(groupId.toString(), currentUserId, false);
        MeltCloudGroup group = groupService.getById(groupId);
        if (!group.getType().equals("1"))
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群并非超级群聊！");
        if (group.getIsDismiss().equals("1"))
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该超级群已解散！");
        if (group.getNotPublic() == 0) {
            group.setNotPublic(1);
        } else {
            group.setNotPublic(0);
        }
        groupService.updateById(group);
        return ServerResponseEntity.success();
    }

    public ServerResponseEntity isGroupMember(Long groupId, String userId) throws Exception {
        MeltCloudGroup group = groupService.getById(groupId);
        if (Objects.isNull(group) || group.getIsDismiss().equals("1"))
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群不存在或已解散！");
        Boolean status = false;
        if (group.getType().equals("1")) {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", userId);
            map.put("groupId", groupId);
            JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/member/exist.json", map);
            if (jsonObject.getInteger("code").equals(200)) {
                status = jsonObject.getBoolean("status");
            }
        } else {
            MeltCloudGroupUser groupUser = groupUserService.getOne(Wrappers.lambdaQuery(MeltCloudGroupUser.class)
                    .eq(MeltCloudGroupUser::getGroupId, groupId).eq(MeltCloudGroupUser::getUserId, userId).eq(MeltCloudGroupUser::getIsDel, 0));
            if (Objects.nonNull(groupUser)) {
                status = true;
            }
        }
        return ServerResponseEntity.success(status);
    }

    public ServerResponseEntity cancelAutoRenewal (Long groupId) {
        operationPermissionVerification(String.valueOf(groupId), null, false);
        MeltCloudUltraGroupApply one = ultraGroupApplyService.getOne(Wrappers.lambdaQuery(MeltCloudUltraGroupApply.class).eq(MeltCloudUltraGroupApply::getGroupId, groupId));
        if (one.getStatus() != 3) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群未成功创建");
        }
        MeltCloudUltraGroupCost groupCost = ultraGroupCostService.getById(one.getCostId());
        if (groupCost.getIsRenew() != 1) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群未开通连续包月");
        }
        one.setCancelRenewal(1);
        ultraGroupApplyService.updateById(one);
        return ServerResponseEntity.success();
    }


    /**
     * 检查超级群到期操作权限
     * @param groupId 群id
     * @param cUserId 当前人id
     * @param outside true:外部接口  false:内部接口
     * @return
     */
    public Boolean ultraGroupExpireCheck(String groupId, String cUserId, boolean outside) {
        boolean result = true;
        MeltCloudGroup group = groupService.getById(groupId);
        if (group.getType().equals("1") && group.getIsArrears() == 1) {
            UserInfoInTokenBO userBO = AuthUserContext.get();
            if (Objects.nonNull(userBO)) {
                if (userBO.getSysType().equals(1)) {
                    cUserId = "shop_" + userBO.getUserId();
                } else if (userBO.getSysType().equals(2)) {
                    cUserId = "plat_" + userBO.getUserId();
                } else if (userBO.getSysType().equals(0)) {
                    cUserId = userBO.getUserId();
                }
            }
            if (StringUtils.isEmpty(cUserId)) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "操作人不能为空！");
            }
            if (group.getCreatorUserId().equals(cUserId)) {
                result = false;
            } else {
                MeltCloudGroupUser groupUser = groupUserService.getOne(Wrappers.lambdaQuery(MeltCloudGroupUser.class)
                        .eq(MeltCloudGroupUser::getGroupId, groupId).eq(MeltCloudGroupUser::getUserId, cUserId).eq(MeltCloudGroupUser::getIsManage, 1));
                if (Objects.nonNull(groupUser)) {
                    result = false;
                }
            }
        }
        if (!outside && !result) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群已欠费，不能操作！");
        }
        return result;
    }



}
